import { Character, Player, GameState, GameContext, GameError, GameErrorType } from '../types';
import { allCharacters } from '../data/characters';

export class CharacterManager {
  /**
   * 获取所有角色
   */
  getAllCharacters(): Character[] {
    return allCharacters;
  }

  /**
   * 根据ID获取角色
   */
  getCharacterById(id: string): Character | undefined {
    return allCharacters.find(char => char.id === id);
  }

  /**
   * 触发被动能力
   */
  triggerPassiveAbility(player: Player, context: GameContext): void {
    const ability = player.character.passiveAbility;
    
    try {
      ability.effect(context);
    } catch (error) {
      console.error(`被动能力执行失败: ${ability.name}`, error);
    }
  }

  /**
   * 使用主动能力
   */
  useActiveAbility(playerId: string, gameState: GameState, targetPlayerId?: string, targetPropertyId?: string): boolean {
    const player = gameState.players.find(p => p.id === playerId);
    if (!player) {
      throw new GameError(GameErrorType.INVALID_MOVE, '玩家不存在');
    }

    const ability = player.character.activeAbility;
    
    // 检查冷却时间
    if (!this.checkCooldown(player, gameState.turn)) {
      const turnsRemaining = (ability.cooldownTurns || 0) - (gameState.turn - player.abilityLastUsed);
      throw new GameError(
        GameErrorType.ABILITY_ON_COOLDOWN, 
        `能力冷却中，还需${turnsRemaining}回合`
      );
    }

    // 根据角色执行不同的主动能力
    const context: GameContext = {
      gameState,
      currentPlayer: player,
    };

    switch (player.character.id) {
      case 'business-tycoon':
        // 强制交换地块
        if (!targetPlayerId || !targetPropertyId) {
          throw new GameError(GameErrorType.INVALID_MOVE, '需要指定目标玩家和地块');
        }
        this.executeBusinessTycoonActive(player, targetPlayerId, targetPropertyId, gameState);
        break;

      case 'lucky-charm':
        // 下次免费
        player.items.push({
          id: 'lucky-shield',
          name: '幸运护盾',
          description: '下次停留位置免除所有费用',
          effect: () => {},
        });
        break;

      case 'architect':
        // 免费升级
        if (!targetPropertyId) {
          throw new GameError(GameErrorType.INVALID_MOVE, '需要指定要升级的地块');
        }
        this.executeArchitectActive(player, targetPropertyId, gameState);
        break;

      case 'banker':
        // 无息贷款
        ability.effect(context);
        break;

      case 'traveler':
        // 传送
        if (targetPropertyId === undefined) {
          throw new GameError(GameErrorType.INVALID_MOVE, '需要指定目标位置');
        }
        const targetPosition = parseInt(targetPropertyId);
        if (isNaN(targetPosition) || targetPosition < 0 || targetPosition >= 40) {
          throw new GameError(GameErrorType.INVALID_MOVE, '无效的目标位置');
        }
        player.position = targetPosition;
        break;

      case 'negotiator':
        // 强制交易
        if (!targetPlayerId) {
          throw new GameError(GameErrorType.INVALID_MOVE, '需要指定目标玩家');
        }
        // 标记为强制交易，UI会处理
        player.items.push({
          id: 'forced-trade',
          name: '强制交易',
          description: `与${targetPlayerId}的强制交易`,
          effect: () => {},
        });
        break;

      default:
        ability.effect(context);
    }

    // 更新最后使用时间
    player.abilityLastUsed = gameState.turn;

    return true;
  }

  /**
   * 商业大亨主动能力：强制交换地块
   */
  private executeBusinessTycoonActive(player: Player, targetPlayerId: string, targetPropertyId: string, gameState: GameState): void {
    const targetPlayer = gameState.players.find(p => p.id === targetPlayerId);
    if (!targetPlayer) {
      throw new GameError(GameErrorType.INVALID_MOVE, '目标玩家不存在');
    }

    if (player.properties.length === 0) {
      throw new GameError(GameErrorType.INVALID_MOVE, '你没有可交换的地块');
    }

    if (!targetPlayer.properties.includes(targetPropertyId)) {
      throw new GameError(GameErrorType.INVALID_MOVE, '目标玩家不拥有该地块');
    }

    // 交换第一个地块
    const myProperty = player.properties[0];
    const theirProperty = targetPropertyId;

    // 更新所有权
    const myProp = gameState.board.find(s => s.property?.id === myProperty)?.property;
    const theirProp = gameState.board.find(s => s.property?.id === theirProperty)?.property;

    if (myProp) myProp.owner = targetPlayerId;
    if (theirProp) theirProp.owner = player.id;

    // 更新玩家地块列表
    player.properties = player.properties.filter(p => p !== myProperty);
    player.properties.push(theirProperty);

    targetPlayer.properties = targetPlayer.properties.filter(p => p !== theirProperty);
    targetPlayer.properties.push(myProperty);
  }

  /**
   * 建筑师主动能力：免费升级
   */
  private executeArchitectActive(player: Player, propertyId: string, gameState: GameState): void {
    const boardSpace = gameState.board.find(s => s.property?.id === propertyId);
    const property = boardSpace?.property;

    if (!property) {
      throw new GameError(GameErrorType.PROPERTY_NOT_AVAILABLE, '地块不存在');
    }

    if (property.owner !== player.id) {
      throw new GameError(GameErrorType.INVALID_MOVE, '你不拥有该地块');
    }

    if (property.level >= property.rent.length - 1) {
      throw new GameError(GameErrorType.INVALID_MOVE, '已达到最高等级');
    }

    // 免费升级
    property.level += 1;
  }

  /**
   * 检查冷却时间
   */
  checkCooldown(player: Player, currentTurn: number): boolean {
    const ability = player.character.activeAbility;
    const cooldownTurns = ability.cooldownTurns || 0;
    
    // 如果从未使用过，可以使用
    if (player.abilityLastUsed === 0) {
      return true;
    }

    // 检查是否已经过了冷却时间
    const turnsSinceLastUse = currentTurn - player.abilityLastUsed;
    return turnsSinceLastUse >= cooldownTurns;
  }

  /**
   * 获取剩余冷却回合数
   */
  getRemainingCooldown(player: Player, currentTurn: number): number {
    const ability = player.character.activeAbility;
    const cooldownTurns = ability.cooldownTurns || 0;
    
    if (player.abilityLastUsed === 0) {
      return 0;
    }

    const turnsSinceLastUse = currentTurn - player.abilityLastUsed;
    const remaining = cooldownTurns - turnsSinceLastUse;
    
    return Math.max(0, remaining);
  }

  /**
   * 重置玩家能力冷却
   */
  resetCooldown(player: Player): void {
    player.abilityLastUsed = 0;
  }
}

// 导出单例实例
export const characterManager = new CharacterManager();
